//
//  SPPreferencePane.m
//  snomPhone
//
//  Created by Daniel Hazelbaker on 11/5/08.
//  Copyright 2008 Blue Box Moon. All rights reserved.
//

#import "SPPreferencePane.h"
#import "BMPreferences.h"
#import "BMPluginController.h"
#import "preferences.h"
#import "comBlueboxmoonPhoneABLookup.h"
#import "comBlueboxmoonPhoneiTunes.h"
#import "comBlueboxmoonPhoneWebLookup.h"
#import "comBlueboxmoonPhoneHover.h"


@implementation SPPreferencePane


//
// Initialize the preference pane.
//
- (id)initWithBundle:(NSBundle *)bundle
{
    if ([super initWithBundle:bundle] == nil)
	return nil;

    [comBlueboxmoonPhoneABLookup setDefaultPreferences];
    [comBlueboxmoonPhoneiTunes setDefaultPreferences];
    [comBlueboxmoonPhoneWebLookup setDefaultPreferences];
    [comBlueboxmoonPhoneHover setDefaultPreferences];

    return self;
}


//
// The view has loaded, read our preferences.
//
- (void)mainViewDidLoad
{
    NSAppleEventDescriptor  *returnObject;
    NSAppleScript	    *scriptObject;
    NSDictionary	    *error = nil;
    int			    i;


    //
    // Set initial values.
    //
    [self setValue:[BMPreferences preferencesWithIdentifier:@"com.blueboxmoon.snomPhone"] forKey:@"preferences"];

    //
    // Detect initial settings.
    //
    [self willChangeValueForKey:@"clickToDial"];
    clickToDial = [NSNumber numberWithBool:[[NSFileManager defaultManager] fileExistsAtPath:[[NSString stringWithFormat:@"~/Library/Address Book Plug-Ins/snomDial.bundle"] stringByExpandingTildeInPath]]];
    [self didChangeValueForKey:@"clickToDial"];

    //
    // Determine if we are a login item.
    //
    scriptObject = [[NSAppleScript alloc] initWithSource:[NSString stringWithFormat:@"tell application \"System Events\"\n"
			"    return (name of every login item)\n"
			"end tell\n"]];
    returnObject = [scriptObject executeAndReturnError:&error];
    for (i = 1; i <= [returnObject numberOfItems]; i++) {
	if ([[[returnObject descriptorAtIndex:i] stringValue] isEqual:@"snomStatus"] == YES) {
	    [self willChangeValueForKey:@"runAtLogin"];
	    runAtLogin = [NSNumber numberWithBool:YES];
	    [self didChangeValueForKey:@"runAtLogin"];

	    break;
	}
    }
    [scriptObject release];
    
    //
    // Check for forced MCX values.
    //
    if ([preferences valueIsForcedForKey:PREFERENCE_IPADDRESS])
	[tfIpAddress setEnabled:NO];
    if ([preferences valueIsForcedForKey:kWebLookupWebAddressKey])
	[tfWebLookupUrl setEnabled:NO];

    //
    // Update the application status.
    //
    [self updateApplicationStatus];
}


//
// Save the preferences if they need to be saved.
//
- (void)willUnselect
{
}


//
// Set wether or not the run the phone status in the menu bar at login.
//
- (void)setRunAtLogin:(NSNumber *)status
{
    NSAppleScript   *scriptObject;
    NSDictionary    *error = nil;
    NSString	    *statusPath;


    //
    // Save the status.
    //
    [runAtLogin autorelease];
    runAtLogin = [status retain];

    //
    // Set the statusPath.
    //
    statusPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"snomStatus" ofType:@"app"];

    if ([status boolValue] == YES) {
	//
	// Turn on phone status.
	//
	[preferences synchronize];
	[[NSWorkspace sharedWorkspace] launchApplication:statusPath];

	//
	// Make it a login item.
	//
	scriptObject = [[NSAppleScript alloc] initWithSource:[NSString stringWithFormat:@"tell application \"System Events\"\n"
				"    if \"%@\" is not in (path of every login item) then\n"
				"        make login item at end with properties {hidden: false, path:\"%@\"}\n"
				"    end if\n"
				"end tell\n", statusPath, statusPath]];
	[scriptObject executeAndReturnError:&error];
	[scriptObject release];
    }
    else {
	//
	// Turn off phone status.
	//
	scriptObject = [[NSAppleScript alloc] initWithSource:@"tell application \"snomStatus\" to quit"];
	[scriptObject executeAndReturnError:&error];
	[scriptObject release];

	//
	// Remove it as a login item.
	//
	scriptObject = [[NSAppleScript alloc] initWithSource:[NSString stringWithFormat:@"tell application \"System Events\"\n"
				"    delete (every login item whose name is \"snomStatus\")\n"
				"end tell\n"]];
	[scriptObject executeAndReturnError:&error];
	[scriptObject release];
    }
}


//
// Set wether or not the Address Book plugin is installed.
//
- (void)setClickToDial:(NSNumber *)value
{
    NSString	*path;


    //
    // Save the value.
    //
    [clickToDial autorelease];
    clickToDial = [value retain];

    path = [[NSString stringWithFormat:@"~/Library/Address Book Plug-Ins/snomDial.bundle"] stringByExpandingTildeInPath];

    if ([value boolValue] == YES) {
	//
	// Copy the plug-in in place if it does not already exist.
	//
	[preferences synchronize];
	if ([[NSFileManager defaultManager] fileExistsAtPath:path] == NO)
	    [[NSFileManager defaultManager] copyPath:[[NSBundle bundleForClass:[self class]] pathForResource:@"snomDial" ofType:@"bundle"] toPath:path handler:NULL];
    }
    else {
	//
	// Remove the plug-in.
	//
	[[NSFileManager defaultManager] removeFileAtPath:path handler:NULL];
    }
}


//
// Set a preference value.
//
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath
{
    if ([keyPath rangeOfString:@"preferences."].location == NSNotFound)
	[super valueForKeyPath:keyPath];
    else
    {
	[self willChangeValueForKey:@"preferences"];
	[preferences setValue:value forKeyPath:[keyPath substringFromIndex:12]];
	[preferences synchronize];
	[self didChangeValueForKey:@"preferences"];
    }
}


//
// Retrieve a preference value.
//
- (id)valueForKeyPath:(NSString *)keyPath
{
    if ([keyPath rangeOfString:@"preferences."].location == NSNotFound)
	return [super valueForKeyPath:keyPath];
    
    return [preferences valueForKeyPath:[keyPath substringFromIndex:12]];
}


//
// Update the state of the application running status.
//
- (void)updateApplicationStatus
{
    if ([self applicationIsRunning])
    {
	[tfMenuStatus setStringValue:@"Phone application is currently running."];
	[startStopButton setTitle:@"Stop"];
    }
    else
    {
	[tfMenuStatus setStringValue:@"Phone application is not running."];
	[startStopButton setTitle:@"Start"];
    }
}


//
// Determine if the application is currently running.
//
- (BOOL)applicationIsRunning
{
    ProcessSerialNumber psn = { 0, kNoProcess };
    CFStringRef		stringRef;
    BOOL		application = NO;
    
    
    //
    // Walk the entire process tree.
    //
    while (!GetNextProcess(&psn)) {
	if (psn.lowLongOfPSN == kNoProcess)
	    break;
	
	CopyProcessName(&psn, &stringRef);
	if ([(NSString *)stringRef isEqual:@"snomStatus"] == YES) {
	    application = YES;
	    CFRelease(stringRef);
	    break;
	}
	CFRelease(stringRef);
    }
    
    return application;
}


//
// Start or stop the phone status.
//
- (IBAction)btnStartStopApplication:(NSButton *)sender
{
    if ([[sender title] isEqual:@"Start"])
    {
	NSString    *statusPath;

	statusPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"snomStatus" ofType:@"app"];
	[[NSWorkspace sharedWorkspace] launchApplication:statusPath];
    }
    else
    {
	[self killApplication];
    }

    //
    // Wait 2 seconds and then update application status.
    //
    [NSThread sleepForTimeInterval:2];
    [self updateApplicationStatus];
}


//
// Determine if the application is currently running.
//
- (void)killApplication
{
    ProcessSerialNumber psn = { 0, kNoProcess };
    CFStringRef		stringRef;
    
    
    //
    // Walk the entire process tree.
    //
    while (!GetNextProcess(&psn)) {
	if (psn.lowLongOfPSN == kNoProcess)
	    break;
	
	CopyProcessName(&psn, &stringRef);
	if ([(NSString *)stringRef isEqual:@"snomStatus"] == YES) {
	    KillProcess(&psn);
	    break;
	}
	CFRelease(stringRef);
    }
}



@end
